1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package java.awt;
26
27 import java.awt.AWTException;
28 import java.awt.Point;
29 import java.awt.Toolkit;
30
31 import java.io.File;
32 import java.io.FileInputStream;
33
34 import java.beans.ConstructorProperties;
35 import java.util.Hashtable;
36 import java.util.Properties;
37 import java.util.StringTokenizer;
38
39 import java.security.AccessController;
40
41 import sun.util.logging.PlatformLogger;
42
43
44
45
46
47
48
49 public class Cursor implements java.io.Serializable {
50
51
52
53
54 public static final int DEFAULT_CURSOR = 0;
55
56
57
58
59 public static final int CROSSHAIR_CURSOR = 1;
60
61
62
63
64 public static final int TEXT_CURSOR = 2;
65
66
67
68
69 public static final int WAIT_CURSOR = 3;
70
71
72
73
74 public static final int SW_RESIZE_CURSOR = 4;
75
76
77
78
79 public static final int SE_RESIZE_CURSOR = 5;
80
81
82
83
84 public static final int NW_RESIZE_CURSOR = 6;
85
86
87
88
89 public static final int NE_RESIZE_CURSOR = 7;
90
91
92
93
94 public static final int N_RESIZE_CURSOR = 8;
95
96
97
98
99 public static final int S_RESIZE_CURSOR = 9;
100
101
102
103
104 public static final int W_RESIZE_CURSOR = 10;
105
106
107
108
109 public static final int E_RESIZE_CURSOR = 11;
110
111
112
113
114 public static final int HAND_CURSOR = 12;
115
116
117
118
119 public static final int MOVE_CURSOR = 13;
120
121
122
123
124
125 @Deprecated
126 protected static Cursor predefined[] = new Cursor[14];
127
128
129
130
131 private final static Cursor[] predefinedPrivate = new Cursor[14];
132
133
134 static final String[][] cursorProperties = {
135 { "AWT.DefaultCursor", "Default Cursor" },
136 { "AWT.CrosshairCursor", "Crosshair Cursor" },
137 { "AWT.TextCursor", "Text Cursor" },
138 { "AWT.WaitCursor", "Wait Cursor" },
139 { "AWT.SWResizeCursor", "Southwest Resize Cursor" },
140 { "AWT.SEResizeCursor", "Southeast Resize Cursor" },
141 { "AWT.NWResizeCursor", "Northwest Resize Cursor" },
142 { "AWT.NEResizeCursor", "Northeast Resize Cursor" },
143 { "AWT.NResizeCursor", "North Resize Cursor" },
144 { "AWT.SResizeCursor", "South Resize Cursor" },
145 { "AWT.WResizeCursor", "West Resize Cursor" },
146 { "AWT.EResizeCursor", "East Resize Cursor" },
147 { "AWT.HandCursor", "Hand Cursor" },
148 { "AWT.MoveCursor", "Move Cursor" },
149 };
150
151
152
153
154
155
156
157
158 int type = DEFAULT_CURSOR;
159
160
161
162
163 public static final int CUSTOM_CURSOR = -1;
164
165
166
167
168
169 private static final Hashtable systemCustomCursors = new Hashtable(1);
170 private static final String systemCustomCursorDirPrefix = initCursorDir();
171
172 private static String initCursorDir() {
173 String jhome = (String) java.security.AccessController.doPrivileged(
174 new sun.security.action.GetPropertyAction("java.home"));
175 return jhome +
176 File.separator + "lib" + File.separator + "images" +
177 File.separator + "cursors" + File.separator;
178 }
179
180 private static final String systemCustomCursorPropertiesFile = systemCustomCursorDirPrefix + "cursors.properties";
181
182 private static Properties systemCustomCursorProperties = null;
183
184 private static final String CursorDotPrefix = "Cursor.";
185 private static final String DotFileSuffix = ".File";
186 private static final String DotHotspotSuffix = ".HotSpot";
187 private static final String DotNameSuffix = ".Name";
188
189
190
191
192 private static final long serialVersionUID = 8028237497568985504L;
193
194 private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Cursor");
195
196 static {
197
198 Toolkit.loadLibraries();
199 if (!GraphicsEnvironment.isHeadless()) {
200 initIDs();
201 }
202 }
203
204
205
206
207
208 private static native void initIDs();
209
210
211
212
213 private transient long pData;
214
215 private transient Object anchor = new Object();
216
217 static class CursorDisposer implements sun.java2d.DisposerRecord {
218 volatile long pData;
219 public CursorDisposer(long pData) {
220 this.pData = pData;
221 }
222 public void dispose() {
223 if (pData != 0) {
224 finalizeImpl(pData);
225 }
226 }
227 }
228 transient CursorDisposer disposer;
229 private void setPData(long pData) {
230 this.pData = pData;
231 if (GraphicsEnvironment.isHeadless()) {
232 return;
233 }
234 if (disposer == null) {
235 disposer = new CursorDisposer(pData);
236
237 if (anchor == null) {
238 anchor = new Object();
239 }
240 sun.java2d.Disposer.addRecord(anchor, disposer);
241 } else {
242 disposer.pData = pData;
243 }
244 }
245
246
247
248
249
250
251
252 protected String name;
253
254
255
256
257
258
259
260
261
262 static public Cursor getPredefinedCursor(int type) {
263 if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
264 throw new IllegalArgumentException("illegal cursor type");
265 }
266 Cursor c = predefinedPrivate[type];
267 if (c == null) {
268 predefinedPrivate[type] = c = new Cursor(type);
269 }
270
271 if (predefined[type] == null) {
272 predefined[type] = c;
273 }
274 return c;
275 }
276
277
278
279
280
281
282
283
284
285
286 static public Cursor getSystemCustomCursor(final String name)
287 throws AWTException, HeadlessException {
288 GraphicsEnvironment.checkHeadless();
289 Cursor cursor = (Cursor)systemCustomCursors.get(name);
290
291 if (cursor == null) {
292 synchronized(systemCustomCursors) {
293 if (systemCustomCursorProperties == null)
294 loadSystemCustomCursorProperties();
295 }
296
297 String prefix = CursorDotPrefix + name;
298 String key = prefix + DotFileSuffix;
299
300 if (!systemCustomCursorProperties.containsKey(key)) {
301 if (log.isLoggable(PlatformLogger.FINER)) {
302 log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
303 }
304 return null;
305 }
306
307 final String fileName =
308 systemCustomCursorProperties.getProperty(key);
309
310 String localized = (String)systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
311
312 if (localized == null) localized = name;
313
314 String hotspot = (String)systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
315
316 if (hotspot == null)
317 throw new AWTException("no hotspot property defined for cursor: " + name);
318
319 StringTokenizer st = new StringTokenizer(hotspot, ",");
320
321 if (st.countTokens() != 2)
322 throw new AWTException("failed to parse hotspot property for cursor: " + name);
323
324 int x = 0;
325 int y = 0;
326
327 try {
328 x = Integer.parseInt(st.nextToken());
329 y = Integer.parseInt(st.nextToken());
330 } catch (NumberFormatException nfe) {
331 throw new AWTException("failed to parse hotspot property for cursor: " + name);
332 }
333
334 try {
335 final int fx = x;
336 final int fy = y;
337 final String flocalized = localized;
338
339 cursor = (Cursor) java.security.AccessController.doPrivileged(
340 new java.security.PrivilegedExceptionAction() {
341 public Object run() throws Exception {
342 Toolkit toolkit = Toolkit.getDefaultToolkit();
343 Image image = toolkit.getImage(
344 systemCustomCursorDirPrefix + fileName);
345 return toolkit.createCustomCursor(
346 image, new Point(fx,fy), flocalized);
347 }
348 });
349 } catch (Exception e) {
350 throw new AWTException(
351 "Exception: " + e.getClass() + " " + e.getMessage() +
352 " occurred while creating cursor " + name);
353 }
354
355 if (cursor == null) {
356 if (log.isLoggable(PlatformLogger.FINER)) {
357 log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
358 }
359 } else {
360 systemCustomCursors.put(name, cursor);
361 }
362 }
363
364 return cursor;
365 }
366
367
368
369
370 static public Cursor getDefaultCursor() {
371 return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
372 }
373
374
375
376
377
378
379
380 @ConstructorProperties({"type"})
381 public Cursor(int type) {
382 if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
383 throw new IllegalArgumentException("illegal cursor type");
384 }
385 this.type = type;
386
387
388 name = Toolkit.getProperty(cursorProperties[type][0],
389 cursorProperties[type][1]);
390 }
391
392
393
394
395
396
397
398
399
400 protected Cursor(String name) {
401 this.type = Cursor.CUSTOM_CURSOR;
402 this.name = name;
403 }
404
405
406
407
408 public int getType() {
409 return type;
410 }
411
412
413
414
415
416
417 public String getName() {
418 return name;
419 }
420
421
422
423
424
425
426 public String toString() {
427 return getClass().getName() + "[" + getName() + "]";
428 }
429
430
431
432
433 private static void loadSystemCustomCursorProperties() throws AWTException {
434 synchronized(systemCustomCursors) {
435 systemCustomCursorProperties = new Properties();
436
437 try {
438 AccessController.doPrivileged(
439 new java.security.PrivilegedExceptionAction() {
440 public Object run() throws Exception {
441 FileInputStream fis = null;
442 try {
443 fis = new FileInputStream(
444 systemCustomCursorPropertiesFile);
445 systemCustomCursorProperties.load(fis);
446 } finally {
447 if (fis != null)
448 fis.close();
449 }
450 return null;
451 }
452 });
453 } catch (Exception e) {
454 systemCustomCursorProperties = null;
455 throw new AWTException("Exception: " + e.getClass() + " " +
456 e.getMessage() + " occurred while loading: " +
457 systemCustomCursorPropertiesFile);
458 }
459 }
460 }
461
462 private native static void finalizeImpl(long pData);
463 }